home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Games: Greatest Hits 1996
/
Amiga Games: Greatest Hits 1996.iso
/
archive
/
userbox
/
publicdomain
/
xfd.lha
/
xfd
/
Developper
/
autodoc
/
xfdsub.doc
< prev
Wrap
Text File
|
1996-08-03
|
10KB
|
303 lines
TABLE OF CONTENTS
xfdForeman/--Overview--
xfdSlave/--Overview--
xfdSlave/DecrunchBufferXYZ
xfdSlave/DecrunchSegmentXYZ
xfdSlave/RecogBufferXYZ
xfdSlave/RecogSegmentXYZ
xfdSlave/ScanDataXYZ
xfdSlave/VerifyDataXYZ
xfdForeman/--Overview-- xfdForeman/--Overview--
The xfdForeman structure is just some kind of header for external slaves.
It protects the slaves from being executed accidentally by having a small
piece of code (moveq #-1,d0 : rts) in the first 4 bytes.
The master can identify a valid bunch of external slaves by checking the
first few bytes of the file for the foreman identification.
Finally, a foreman holds the pointer to a linked list of slaves and thus
enables the master to work with these slaves.
xfdSlave/--Overview-- xfdSlave/--Overview--
The xfdSlave structure is the heart of the whole library system. Each slave
enables the master to recognize and decrunch packed files. Additionally,
slaves of the type XFDPFB_RELOC can recognize and decrunch segments.
Slaves with XFDPFB_DATA flag set contain routines for data scan and data
verification.
Therefore each slave contains 4 routines that are called from the master.
Pointers to these are stored in xfds_RecogBuffer and xfds_DecrunchBuffer.
XFDPFB_RELOC slaves have xfds_RecogSegment and xfds_DecrunchSegment
initialized, XFDPFB_DATA slaves use xfds_ScanData and xfds_VerifyData.
All routines have one thing in common: the CPU registers D0/D1/A0/A1 are
so-called scratch registers, they may change during execution, all other
registers must remain unchanged. CPU register A6 holds a pointer to the
xfdMasterBase structure. See chapters below for a description of the slave
routines.
ALL SLAVE ROUTINES MUST BE REENTRANT! NEVER STORE ANY DATA IN STATIC MEMORY
AREAS, USE THE STACK OR SOME ALLOCATED MEMORY INSTEAD! REMEMBER THAT THE
ROUTINES MIGHT BE CALLED BY SEVERAL PROGRAMS AT THE SAME TIME!
The name of the packer that is supported by the slave and the flags that
describe the packer are stored in xfds_PackerName and xfds_PackerFlags.
(V36) Internal slaves all have an unique ID value stored in xfds_SlaveID.
This field should be set to NULL for external slaves.
(V36) If you have written a slave that should replace an internal one
because it's faster or otherwise enhanced, simply put the ID of the slave
to be replaced in xfds_ReplaceID. The old slave will then be taken out of
the list of used slaves. Otherwise, xfds_ReplaceID must be NULL.
(V36) xfdRecogBuffer() usually only requires a quite small part of a file
to recognize it properly. To avoid reading the whole file for recognition
purposes, you may set xfds_MinBufferSize to the minimum amount of bytes
that is required to recognize the crunched file correctly.
Note that xfdRecogBuffer() uses this value internally to decide whether
a file might be crunched with a packer or not, so you don't have to do
an extra size comparison in your xfds_RecogBuffer function any more.
For packer headers with non-constant sizes, simply set xfds_MinBufferSize
to a value that will ensure correct recognition of all possible files.
Whenever you intend to use features of the xfdmaster.library in your slaves
that are marked (V34) or higher, make sure to set xfds_MasterVersion to
the desired version number, otherwise an old library version might crash
while using the new slave.
xfdSlave/DecrunchBufferXYZ xfdSlave/DecrunchBufferXYZ
NAME
DecrunchBufferXYZ -- Decrunch file from buffer to buffer.
SYNOPSIS
result = DecrunchBufferXYZ(bufferinfo)
D0 A0
BOOL DecrunchBufferXYZ(struct xfdBufferInfo *);
FUNCTION
The typical steps of such a routine are:
- Get length of decrunched file (exactly or a bit too much).
- Allocate memory (with memtype from xfdbi_TargetBufMemType).
- Decrunch file from xfdbi_SourceBuffer to xfdbi_TargetBuffer.
- Initialize all necessary parts of the xfdBufferInfo structure.
- Set xfdbi_Error if an error occurs.
INPUTS
bufferinfo - A valid xfdBufferInfo structure that successfully went
through a call to xfdRecogBuffer().
RESULT
result - TRUE if decrunching succeeded, FALSE if something went wrong.
NOTE
You have to initialize xfds_DecrunchBuffer with a pointer to your
DecrunchBufferXYZ routine.
SEE ALSO
Example sourcecodes.
xfdSlave/DecrunchSegmentXYZ xfdSlave/DecrunchSegmentXYZ
NAME
DecrunchSegmentXYZ -- Decrunch segment list.
SYNOPSIS
result = DecrunchSegmentXYZ(segmentinfo)
D0 A0
BOOL DecrunchSegmentXYZ(struct xfdSegmentInfo *);
FUNCTION
There are two possibilities how to decrunch a segment list. The
first one works like this:
- Modify decrunch header to make it return to the caller.
- Call decrunch header.
- dos.library/UnloadSeg() whole seglist and clear xfdsi_SegList
if an error occurs and the seglist has already been altered
in any way.
- Otherwise only release segments that are no longer necessary.
- Store BPTR to first hunk of decrunched segment list in
xfdsi_SegList.
- Set xfdsi_Error if an error occurs.
The second possibility works the same way as the first with
the difference that you don't jump to the original code, but you
include all necessary parts of it (decrunch routine, relocator)
in your own routine. The big advantage is that you can handle
error conditions much better because most of the standard decrunch
headers in executable files have problems with low memory etc.
(V34) If the decruncher allows it, always support XFDPFB_RELMODE.
That way the caller can determine the type of memory the segments
should be placed in by initializing xfdsi_RelMode with XFDREL_#?.
Many crunchers don't change the hunk structure of the crunched
data. If this is the case, you can simply call the decrunch code
in the segment list and then use xfdRelocate() (V34).
INPUTS
segmentinfo - A valid xfdSegmentInfo structure that successfully went
through a call to xfdRecogSegment().
RESULT
result - TRUE if decrunching succeeded, FALSE if something went wrong.
NOTE
You have to initialize xfds_DecrunchSegment with a pointer to your
DecrunchSegmentXYZ routine.
SEE ALSO
Example sourcecodes.
xfdSlave/RecogBufferXYZ xfdSlave/RecogBufferXYZ
NAME
RecogBufferXYZ -- Recognize crunched file in buffer.
SYNOPSIS
result = RecogBufferXYZ(buffer, length)
D0 A0 D0
BOOL RecogBufferXYZ(APTR, ULONG);
FUNCTION
This routine should examine the buffer for a crunched file.
First thing is to check if the size of the file allows it to
be crunched with the packer in question. After that, simply
do some compares to figure out if the file has been crunched
or not.
(V36) You don't have to do any size comparisons if you set
xfds_MinBufferSize to the minimum amount of bytes that are
necessary for a file to be crunched with that packer.
INPUTS
buffer - Pointer to a buffer that holds the crunched file.
length - Length of that buffer.
RESULT
result - TRUE if packer has been recognized, else FALSE.
NOTE
You have to initialize xfds_RecogBuffer with a pointer to your
RecogBufferXYZ routine.
SEE ALSO
Example sourcecodes.
xfdSlave/RecogSegmentXYZ xfdSlave/RecogSegmentXYZ
NAME
RecogSegmentXYZ -- Recognize crunched segment list.
SYNOPSIS
result = RecogSegmentXYZ(seglist)
D0 A0
BOOL RecogSegmentXYZ(BPTR);
FUNCTION
This routine should examine if a segment list is crunched.
You can check the whole segment list for correct lengths of hunks
and for contents of hunks if you like. There should be at least
3 comparations to determine the cruncher.
INPUTS
seglist - BPTR to first segment.
RESULT
result - TRUE if packer has been recognized, else FALSE.
NOTE
You have to initialize xfds_RecogSegment with a pointer to your
RecogSegmentXYZ routine.
SEE ALSO
Example sourcecodes.
xfdSlave/ScanDataXYZ xfdSlave/ScanDataXYZ
NAME
ScanDataXYZ -- Recognize crunched data in buffer.
SYNOPSIS
result = ScanDataXYZ(buffer, length)
D0 A0 D0
BOOL ScanDataXYZ(APTR, ULONG);
FUNCTION
This routine should only test for the usual data ID at exactly the
address given as buffer. The length is the amount of bytes until
the end of the whole buffer and is of minor use in this context.
You may use it if the ID is several bytes long to test if buffer
is already at its end.
EXAMPLE
ScanDataS400 moveq #0,d0
cmp.l #'S400',(a0) ;StoneCracker Data ID
bne.s .Exit
moveq #1,d0
.Exit rts
INPUTS
buffer - Pointer to a address to scan at.
length - Length of whole buffer.
RESULT
result - TRUE if crunched data has been recognized, else FALSE.
NOTE
You have to initialize xfds_ScanData with a pointer to your
ScanDataXYZ routine.
xfdSlave/VerifyDataXYZ xfdSlave/VerifyDataXYZ
NAME
VerifyDataXYZ -- Check crunched data and return length.
SYNOPSIS
length = VerifyDataXYZ(buffer, length)
D0 A0 D0
ULONG VerifyDataXYZ(APTR, ULONG);
FUNCTION
This routine is called after ScanDataXYZ and first has to check if
the data ID found while scanning is part of a valid data file or
just some piece of code etc.
If it is a valid data file, it has to calculate the final length
of the data file starting at the ID until the end. This value will
then be used for the xfdScanNode structure.
EXAMPLE
VerifyDataS400 moveq #$c,d1
add.l 8(a0),d1 ;crlen
cmp.l d0,d1 ;crlen > buflen ??
bgt.s .Exit
move.l 4(a0),d0
sub.l 8(a0),d0 ;cr > uncr ??
bmi.s .Exit
move.l d1,d0
rts
.Exit moveq #0,d0
rts
INPUTS
buffer - Pointer to start address of possible data file.
length - Length of whole buffer.
RESULT
length - Final length of found data file, else NULL.
NOTE
You have to initialize xfds_VerifyData with a pointer to your
VerifyDataXYZ routine.